import 'dart:convert';
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:path_provider/path_provider.dart';
import 'package:signage/app/constants/template_constants.dart';
import 'package:signage/app/data/models/member_info_item_model.dart';
import 'package:signage/app/modules/profile/fontManager/controllers/font_manager_controller.dart';
import 'package:signage/app/utils/sp_util.dart';
import 'package:signage/l10n/l10n.dart';
import 'package:signage/utils/eink_image_processor.dart';
import 'package:signage/widgets/edit_dialog.dart';
import 'package:uuid/uuid.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/rendering.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:flutter/scheduler.dart';
import '../../../../data/models/board_element.dart';
import '../../../../data/models/template_model.dart';
import '../../../../modules/template/controllers/template_controller.dart';
import '../../../../utils/toast_utils.dart';

class EditTemplateController extends GetxController
    with GetSingleTickerProviderStateMixin {
  final templateName = ''.obs;
  final templateSize = TemplateConstants.defaultTemplateSize.obs;
  final boardElements = <BoardElement>[].obs;
  final Rx<BoardElement?> selectedElement = Rx<BoardElement?>(null);
  final canvasSize = Size.zero.obs;
  final _imagePicker = ImagePicker();
  var aspectRatio = (800 / 480).obs;
  final fontManagerController = Get.find<FontManagerController>();
  // 添加一个 GlobalKey 用于获取画的 RenderObject
  final GlobalKey boardKey = GlobalKey();

  // 添加 SharedPreferences 实例
  // 加编辑模式状态
  final editMode = Rx<EditMode>(EditMode.none);

  // 添加边框显示控制变量
  final showBorders = true.obs;

  // 添加文本计数器
  final _textCounter = 0.obs;

  final selectedSize = AppLocalizations.of(Get.context!)!.translate('all').obs;
  var currentTab = 0.obs;
  final allTemplates = <TemplateModel>[].obs;
  final simpleTemplates = <TemplateModel>[].obs;
  final partyTemplates = <TemplateModel>[].obs;
  final agendaTemplates = <TemplateModel>[].obs;
  final myTemplates = <TemplateModel>[].obs;
  // 生成下一个文本标签
  String _getNextTextLabel() {
    _textCounter.value++;
    return '信息${_textCounter.value}';
  }

  // 添加一个变量控制模板选择区域的显示
  final selectedIndex = 0.obs;

  // 显示模板选择器
  void showTemplatePicker() {
    selectedIndex.value = 0;
    selectedElement.value = null; // 清除当前选中的元素
  }

  // 修改选择元素的方法
  void selectElement(BoardElement element) {
    selectedElement.value = element;
    if (element is ImageBoardElement) {
      selectedIndex.value = 1;
    } else if (element is TextBoardElement) {
      selectedIndex.value = 2;
    } else if (element is ColorBlockBoardElement) {
      selectedIndex.value = 3;
    } else {
      selectedIndex.value = 4;
    }
  }

  late TabController tabController;
  @override
  void onInit() async {
    super.onInit();
    tabController = TabController(length: 5, vsync: this);
    tabController.addListener(() {
      currentTab.value = tabController.index;
    });
    // 获取传入的参数
    final args = Get.arguments;
    templateName.value = args['templateName'];
    templateSize.value = args['size'];

    try {
      final size = templateSize.value.split('|')[1].trim().split('X');
      aspectRatio.value = double.parse(size[0]) / double.parse(size[1]);
      print('aspectRatio: $aspectRatio');
    } catch (e) {}
    canvasSize.value = Size(Get.size.width, Get.size.width / aspectRatio.value);


    // 尝试加载已保存的数据
    await loadTemplate();

    // 如果 boardElements 为空，添加默认背景元素
    if (boardElements.isEmpty) {
      final backgroundElement = BackgroundBoardElement(
        id: const Uuid().v4(),
        initialPosition: Offset.zero,
        initialSize: canvasSize.value,
        initialColor: Color(0XFFFFFFFF),
      );
      boardElements.add(backgroundElement);
    }

    loadTemplates();
  }

  // 添加元素的方法
  Future<void> addImage() async {
    final XFile? image =
        await _imagePicker.pickImage(source: ImageSource.gallery);
    if (image != null) {
      // 裁剪图片
      final croppedFile = await cropImage(File(image.path));
      if (croppedFile != null) {
        print('croppedFile: ${croppedFile.path}');
        try {
          // 读取原始图片
          // 处理图片颜色
          final processedBytes = await EinkImageProcessor.processImage(
              croppedFile.path, ProcessMode.bwLevel);

          // 计算16:9的尺寸，基于画布宽度的一半
          final defaultWidth = canvasSize.value.width * 0.5;
          final defaultHeight = defaultWidth / aspectRatio.value;

          // 计算居中位置
          final centerX = (canvasSize.value.width - defaultWidth) / 2;
          final centerY = (canvasSize.value.height - defaultHeight) / 2;

          final element = ImageBoardElement(
            id: const Uuid().v4(),
            initialPosition: Offset(centerX, centerY),
            initialSize: Size(defaultWidth, defaultHeight),
          );
          element.imagePath.value = processedBytes;
          element.initialImagePath.value = croppedFile.path;
          boardElements.add(element);
          selectedElement.value = element;
          selectedIndex.value = 1;
        } catch (e) {
          print('处理图片失败: $e');
          ToastUtils.showError('处理图片失败: $e');
        }
      }
    }
  }

  Future<CroppedFile?> cropImage(File imageFile) async {
    final croppedFile = await ImageCropper().cropImage(
      sourcePath: imageFile.path,
      compressFormat: ImageCompressFormat.png,
      uiSettings: [
        AndroidUiSettings(
          toolbarTitle: '裁剪图片',
          toolbarColor: Colors.blue,
          toolbarWidgetColor: Colors.white,
          initAspectRatio: CropAspectRatioPreset.original,
          lockAspectRatio: false,
          hideBottomControls: false,
        ),
        IOSUiSettings(
          title: '裁剪图片',
          doneButtonTitle: '完成',
          cancelButtonTitle: '取消',
          aspectRatioLockEnabled: false,
        ),
      ],
    );
    return croppedFile;
  }

  // 修改添加文本方法
  void addText() {
    final initialText = _getNextTextLabel();
    const initialFontSize = 72.0;

    // Create a TextPainter to measure text dimensions
    final textPainter = TextPainter(
      text: TextSpan(
        text: initialText,
        style: TextStyle(
            fontSize: initialFontSize,
            fontFamily: fontManagerController.defaultFontFamily.value),
      ),
      textDirection: TextDirection.ltr,
    )..layout();

    final defaultWidth = textPainter.width;
    final defaultHeight = textPainter.height;

    // Calculate center position
    final centerX = (canvasSize.value.width - defaultWidth) / 2;
    final centerY = (canvasSize.value.height - defaultHeight) / 2;

    final element = TextBoardElement(
      id: 'text_${_textCounter.value}', // 使用计数器作为ID
      initialPosition: Offset(centerX, centerY),
      initialSize: Size(defaultWidth, defaultHeight),
      initialText: initialText,
      initialFontFamily: fontManagerController.defaultFontFamily.value,
      initialFontSize: initialFontSize,
      initialColor: Color(0XFF000000),
    );

    boardElements.add(element);
    selectedElement.value = element;
    selectedIndex.value = 2;
  }

  void loadTemplates() {
    // 深度复制模板数据
    final templatesCopy = TemplateConstants.defaultTemplates.map((template) {
      return Map<String, dynamic>.from(template).map((key, value) {
        if (value is Map) {
          return MapEntry(key, Map<String, dynamic>.from(value));
        } else if (value is List) {
          return MapEntry(key, List.from(value.map((item) {
            if (item is Map) {
              return Map<String, dynamic>.from(item);
            }
            return item;
          })));
        }
        return MapEntry(key, value);
      });
    }).toList();
    
    // 使用复制的数据创建模板
    final systemTemplates = templatesCopy
        .map((data) => TemplateModel.fromJson(data))
        .toList();

    // Replace placeholders with localized text
    for (var template in systemTemplates) {
      // Replace template name
      template.name = template.name.replaceAllMapped(
        RegExp(r'\{(\w+)\}(\d*)'),
        (match) {
          final key = match.group(1) ?? '';
          final number = match.group(2);
          return '${AppLocalizations.of(Get.context!)!.translate(key)}$number';
        }
      );
      
      // Replace category
      template.category = template.category.replaceAllMapped(
        RegExp(r'\{(\w+)\}'),
        (match) => AppLocalizations.of(Get.context!)!.translate(match.group(1) ?? '')
      );
      
      // Replace text elements
      for (var element in template.elements) {
        if (element['type'] == 'text' && element['text'] != null) {
          element['text'] = element['text'].toString().replaceAllMapped(
            RegExp(r'\{(\w+)\}'),
            (match) => AppLocalizations.of(Get.context!)!.translate(match.group(1) ?? '')
          );
        }
      }
    }

    // 从 SharedPreferences 加载用户模板
    final userTemplatesJson = SpUtil.getString('user_templates') ?? '[]';
    final List<dynamic> userTemplatesData = jsonDecode(userTemplatesJson);
    final userTemplates =
        userTemplatesData.map((data) => TemplateModel.fromJson(data)).toList();

    // 更新所有分类的数据
    allTemplates.value = [...systemTemplates, ...userTemplates]
        .where((t) => t.size == selectedSize.value || 
            selectedSize.value == AppLocalizations.of(Get.context!)!.translate('all'))
        .toList();
    simpleTemplates.value = allTemplates
        .where((t) => t.categoryType == TemplateCategoryType.simple)
        .where((t) => t.size == selectedSize.value || 
            selectedSize.value == AppLocalizations.of(Get.context!)!.translate('all'))
        .toList();
    partyTemplates.value = allTemplates
        .where((t) => t.categoryType == TemplateCategoryType.party)
        .where((t) => t.size == selectedSize.value || 
            selectedSize.value == AppLocalizations.of(Get.context!)!.translate('all'))
        .toList();
    agendaTemplates.value = allTemplates
        .where((t) => t.categoryType == TemplateCategoryType.agenda)
        .where((t) => t.size == selectedSize.value || 
            selectedSize.value == AppLocalizations.of(Get.context!)!.translate('all'))
        .toList();
    myTemplates.value = userTemplates
        .where((t) => t.size == selectedSize.value || 
            selectedSize.value == AppLocalizations.of(Get.context!)!.translate('all'))
        .toList();
  }

  void addColorBlock() {
    final element = ColorBlockBoardElement(
      id: const Uuid().v4(),
      initialPosition: Offset(
        0,
        canvasSize.value.height - 40,
      ),
      initialSize: Size(canvasSize.value.width, 40),
      initialColor: Color(0XFFFF0000),
    );
    boardElements.add(element);
    selectedElement.value = element;
    selectedIndex.value = 3;
  }

  // 元素操作方法
  void updateElementPosition(String elementId, Offset newPosition) {
    try {
      final elementIndex = boardElements.indexWhere((e) => e.id == elementId);
      if (elementIndex == -1) return;

      final element = boardElements[elementIndex];
      element.position.value = newPosition;

      // 如果是文本元素，需要更新列表中的元素
      if (element is TextBoardElement) {
        boardElements[elementIndex] = element;
        boardElements.refresh();
      }
    } catch (e) {
      print('更新元素位置失败: $e');
    }
  }

  void updateElementSize(String elementId, Size newSize) {
    final element = boardElements.firstWhere((e) => e.id == elementId);
    element.size.value = newSize;
  }

  void deleteElement(String elementId) {
    boardElements.removeWhere((element) => element.id == elementId);
    if (selectedElement.value?.id == elementId) {
      selectedElement.value = null;
      selectedIndex.value = -1;
    }
  }

  // 图片特定方法
  void updateImageProcessMode(String elementId, ProcessMode processMode) async {
    final element = boardElements.firstWhere(
      (e) => e.id == elementId && e is ImageBoardElement,
    ) as ImageBoardElement;
    element.processMode.value = processMode;
    element.imagePath.value = await EinkImageProcessor.processImage(
        element.initialImagePath.value, processMode);
  }

  void updateBackgroundProcessMode(
      String elementId, ProcessMode processMode) async {
    final element = boardElements
            .firstWhere((e) => e.id == elementId && e is BackgroundBoardElement)
        as BackgroundBoardElement;
    element.processMode.value = processMode;
    element.backgroundImagePath.value = await EinkImageProcessor.processImage(
        element.initialBackgroundImagePath.value, processMode);
    boardElements.refresh();
  }

  // 层级调整方法
  void bringToFront() {
    if (selectedElement.value != null) {
      final element = selectedElement.value!;
      boardElements.remove(element);
      boardElements.add(element);
    }
  }

  void sendToBack() {
    if (selectedElement.value != null) {
      final element = selectedElement.value!;
      boardElements.remove(element);
      boardElements.insert(0, element);
    }
  }

  void moveUp() {
    if (selectedElement.value != null) {
      final currentIndex = boardElements.indexOf(selectedElement.value!);
      if (currentIndex < boardElements.length - 1) {
        final temp = boardElements.toList();
        final element = temp[currentIndex];
        temp[currentIndex] = temp[currentIndex + 1];
        temp[currentIndex + 1] = element;
        boardElements.value = temp;
      }
    }
  }

  void moveDown() {
    if (selectedElement.value != null) {
      final currentIndex = boardElements.indexOf(selectedElement.value!);
      if (currentIndex > 0) {
        final temp = boardElements.toList();
        final element = temp[currentIndex];
        temp[currentIndex] = temp[currentIndex - 1];
        temp[currentIndex - 1] = element;
        boardElements.value = temp;
      }
    }
  }

  // 垂直对齐方法
  void alignTop(String elementId) {
    final element = boardElements.firstWhere((e) => e.id == elementId);
    element.position.value = Offset(element.position.value.dx, 0);
  }

  void alignCenter(String elementId) {
    final element = boardElements.firstWhere((e) => e.id == elementId);
    element.position.value = Offset(
      element.position.value.dx,
      (canvasSize.value.height - element.size.value.height) / 2,
    );
  }

  void alignBottom(String elementId) {
    final element = boardElements.firstWhere((e) => e.id == elementId);
    element.position.value = Offset(
      element.position.value.dx,
      canvasSize.value.height - element.size.value.height,
    );
  }

  // 横向对齐方法
  void alignLeft(String elementId) {
    final element = boardElements.firstWhere((e) => e.id == elementId);
    element.position.value = Offset(0, element.position.value.dy);
  }

  void alignHorizontalCenter(String elementId) {
    final element = boardElements.firstWhere((e) => e.id == elementId);
    print((canvasSize.value.width - element.size.value.width) / 2);
    element.position.value = Offset(
      (canvasSize.value.width - element.size.value.width) / 2,
      element.position.value.dy,
    );
  }

  void alignRight(String elementId) {
    final element = boardElements.firstWhere((e) => e.id == elementId);
    element.position.value = Offset(
      canvasSize.value.width - element.size.value.width,
      element.position.value.dy,
    );
  }

  setBackground() {}

  Future<void> saveAsImage() async {
    try {
      RenderRepaintBoundary boundary =
          boardKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
      ui.Image image = await boundary.toImage(pixelRatio: 3.0);
      final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
      final pngBytes = byteData!.buffer.asUint8List();

      // TODO: 保存图片
    } catch (e) {
      print('保存失败: $e');
    }
  }

  int? getHorizontalAlignment(BoardElement element) {
    final canvasWidth = canvasSize.value.width;
    final elementWidth = element.size.value.width;
    final currentX = element.position.value.dx;

    const threshold = 1; // 允许的误差范围

    if ((currentX - 0).abs() <= threshold) {
      return 1; // 居左
    } else if ((currentX - (canvasWidth - elementWidth) / 2).abs() <=
        threshold) {
      return 2; // 居中
    } else if ((currentX - (canvasWidth - elementWidth)).abs() <= threshold) {
      return 3; // 居右
    }

    return null; // 不处于任何对齐状态
  }

  void alignHorizontal(String elementId, int? alignment) {
    final element = boardElements.firstWhere((e) => e.id == elementId);
    final canvasWidth = canvasSize.value.width;
    final elementWidth = element.size.value.width;

    double newX = 0;
    switch (alignment) {
      case 1: // 居左
        newX = 0;
        break;
      case 2: // 居中
        newX = (canvasWidth - elementWidth) / 2;
        break;
      case 3: // 居右
        newX = canvasWidth - elementWidth;
        break;
    }
    print((372 / canvasSize.value.width) * newX);

    print((372 / canvasSize.value.width) * 126);
    updateElementPosition(
        elementId,
        Offset(
            newX.roundToDouble(), element.position.value.dy.roundToDouble()));
  }

  int? getVerticalAlignment(BoardElement element) {
    final canvasHeight = canvasSize.value.height;
    final elementHeight = element.size.value.height;
    final currentY = element.position.value.dy;

    const threshold = 1; // 允许的误差范围

    if ((currentY - 0).abs() <= threshold) {
      return 1; // 居
    } else if ((currentY - (canvasHeight - elementHeight) / 2).abs() <=
        threshold) {
      return 2; // 居中
    } else if ((currentY - (canvasHeight - elementHeight)).abs() <= threshold) {
      return 3; // 居下
    }

    return null; // 不处于任何对齐状态
  }

  void alignVertical(String elementId, int? alignment) {
    final element = boardElements.firstWhere((e) => e.id == elementId);
    final canvasHeight = canvasSize.value.height;
    final elementHeight = element.size.value.height;

    double newY = 0;
    switch (alignment) {
      case 1: // 居上
        newY = 0;
        break;
      case 2: // 居中
        newY = (canvasHeight - elementHeight) / 2;
        break;
      case 3: // 居下
        newY = canvasHeight - elementHeight;
        break;
    }

    updateElementPosition(
        elementId, Offset(element.position.value.dx, newY.roundToDouble()));
  }

  int? getImageProcessMode(ImageBoardElement element) {
    switch (element.processMode.value) {
      case ProcessMode.bwLevel:
        return 0;
      case ProcessMode.colorLevel:
        return 1;
      case ProcessMode.bwDither:
        return 2;
      case ProcessMode.colorDither:
        return 3;
      case ProcessMode.colorDither2:
        return 4;
      case ProcessMode.bwRedDither:
        return 5;
      case ProcessMode.bwYellowDither:
        return 6;
      case ProcessMode.bwRedYellowDither:
        return 7;
      default:
        return 0;
    }
  }

  void updateImageFit(String elementId, bool isFit) {
    final element = boardElements.firstWhere(
      (e) => e.id == elementId && e is ImageBoardElement,
    ) as ImageBoardElement;
    element.isFit.value = isFit;
  }

  bool getImageFit(ImageBoardElement element) {
    return element.isFit.value;
  }

  Future<void> previewImage() async {
    try {
      showBorders.value = false;

      await SchedulerBinding.instance.endOfFrame;

      RenderRepaintBoundary boundary =
          boardKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
      ui.Image image = await boundary.toImage(pixelRatio: 3.0);
      final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
      final pngBytes = byteData!.buffer.asUint8List();

      showBorders.value = true;

      Get.dialog(
        Dialog(
          backgroundColor: Colors.transparent,
          insetPadding: EdgeInsets.zero, // Remove default padding
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              // Image container
              Container(
                width: Get.width, // Full screen width
                child: Image.memory(
                  pngBytes,
                  fit: BoxFit.contain,
                ),
              ),
              // Close button at bottom
              Container(
                margin: const EdgeInsets.only(top: 20),
                child: TextButton(
                  onPressed: () => Get.back(),
                  child: const Text(
                    '关闭',
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 18,
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
        barrierColor: Colors.black87,
      );
    } catch (e) {
      showBorders.value = true;
      print('预览失败: $e');
    }
  }

  Future<String> saveImageToFile(Uint8List pngBytes, String fileName) async {
    try {
      // 获取应用的文档目录
      final Directory directory = await getApplicationDocumentsDirectory();

      // 创建保存图片的子目录
      final String imagesPath = '${directory.path}/images';
      await Directory(imagesPath).create(recursive: true);

      // 成完整的文件路径
      final String filePath =
          '$imagesPath/${fileName}_${DateTime.now().millisecondsSinceEpoch}.png';

      // 创建文件并写入数据
      final File file = File(filePath);
      await file.writeAsBytes(pngBytes);

      return filePath;
    } catch (e) {
      print('Error saving image: $e');
      throw Exception('Failed to save image');
    }
  }

  // 保存模板
  Future<void> saveTemplate() async {
    try {
      showBorders.value = false;
      await Future.delayed(const Duration(milliseconds: 100));

      final pngBytes = await _capturePreview();

      final String originalTemplateId = Get.arguments['templateId'] ?? '';
      print('originalTemplateId: $originalTemplateId');
      final isSystemTemplate = originalTemplateId.startsWith('system_');
      final String templateId = isSystemTemplate
          ? const Uuid().v4()
          : (originalTemplateId.isEmpty ? const Uuid().v4() : originalTemplateId);

      // 获取 documents 目录
      final docDir = await getApplicationDocumentsDirectory();
      final imagesDir = Directory('${docDir.path}/images');
      if (!await imagesDir.exists()) {
        await imagesDir.create(recursive: true);
      }

      // 保存预览图片
      final previewPath = await saveImageToFile(pngBytes, templateId);

      final now = DateTime.now();
      final dateStr = '${now.month.toString().padLeft(2, '0')}${now.day.toString().padLeft(2, '0')}';
      final templateNameWithDate = isSystemTemplate ? '我的模板$dateStr' : templateName.value;

      final template = TemplateModel(
        id: templateId,
        name: templateNameWithDate,
        width: canvasSize.value.width.toInt(),
        height: canvasSize.value.height.toInt(),
        category: 'custom',
        categoryType: 'custom',
        filePath: previewPath,
        isSystemTemplate: false,
        size: templateSize.value,
      );

      template.memberInfos = boardElements
          .whereType<TextBoardElement>()
          .map((e) => MemberInfoItem(keyName: e.text.value))
          .toList();

      // 移动所有图片文件到永久存储并更新路径
      for (var element in boardElements) {
        if (element is ImageBoardElement) {
          // 移动处理后的图片
          if (element.imagePath.value.startsWith(await _getCachePath())) {
            final newPath = await _moveFileToDocuments(element.imagePath.value);
            element.imagePath.value = newPath;
          }
          // 移动原始图片
          if (element.initialImagePath.value.startsWith(await _getCachePath())) {
            final newPath = await _moveFileToDocuments(element.initialImagePath.value);
            element.initialImagePath.value = newPath;
          }
        } else if (element is BackgroundBoardElement && element.backgroundImagePath.value.isNotEmpty) {
          // 移动背景图片
          if (element.backgroundImagePath.value.startsWith(await _getCachePath())) {
            final newPath = await _moveFileToDocuments(element.backgroundImagePath.value);
            element.backgroundImagePath.value = newPath;
          }
          // 移动原始背景图片
          if (element.initialBackgroundImagePath.value.startsWith(await _getCachePath())) {
            final newPath = await _moveFileToDocuments(element.initialBackgroundImagePath.value);
            element.initialBackgroundImagePath.value = newPath;
          }
        }
      }

      template.setElementsFromBoardElements(boardElements);

      final templateController = Get.find<TemplateController>();
      templateController.addTemplate(template);
      templateController.updateTemplate(template);

      showBorders.value = true;
      Get.back();
      ToastUtils.showSuccess(AppLocalizations.of(Get.context!)!.translate('template_saved'));
    } catch (e) {
      showBorders.value = true;
      print('保存失败: $e');
      ToastUtils.showError(AppLocalizations.of(Get.context!)!.translate('save_template_failed'));
    }
  }

  // 获取缓存路径
  Future<String> _getCachePath() async {
    final cacheDir = await getApplicationCacheDirectory();
    return cacheDir.path;
  }

  // 移动文件到 documents 目录
  Future<String> _moveFileToDocuments(String sourcePath) async {
    try {
      final sourceFile = File(sourcePath);
      if (!await sourceFile.exists()) return sourcePath;

      final docDir = await getApplicationDocumentsDirectory();
      final fileName = sourcePath.split('/').last;
      final targetPath = '${docDir.path}/images/$fileName';

      // 如果目标文件已存在，直接返回目标路径
      if (await File(targetPath).exists()) {
        return targetPath;
      }

      // 确保目标目录存在
      await Directory('${docDir.path}/images').create(recursive: true);

      // 移动文件
      await sourceFile.copy(targetPath);
      await sourceFile.delete();

      return targetPath;
    } catch (e) {
      print('移动文件失败: $e');
      return sourcePath;
    }
  }

  // 加载模板
  Future<void> loadTemplate() async {
    try {
      final String? templateId = Get.arguments['templateId'];
      if (templateId == null) return;

      // Wait for the next frame to ensure the widget tree is built
      await SchedulerBinding.instance.endOfFrame;
      
      // Check if it's a system template
      if (templateId.startsWith('system_')) {
        // Show alert dialog
        await Get.dialog(
          TipsDialog(
            title: AppLocalizations.of(Get.context!)!.translate('tips'),
            text: AppLocalizations.of(Get.context!)!.translate('system_template_edit_tips'),
          ),
        );

        // 深度复制系统模板数据
        final systemTemplate = Map<String, dynamic>.from(
          TemplateConstants.defaultTemplates.firstWhere(
            (template) => template['id'] == templateId,
            orElse: () => throw Exception('System template not found'),
          ),
        ).map((key, value) {
          if (value is Map) {
            return MapEntry(key, Map<String, dynamic>.from(value));
          } else if (value is List) {
            return MapEntry(key, List.from(value.map((item) {
              if (item is Map) {
                return Map<String, dynamic>.from(item);
              }
              return item;
            })));
          }
          return MapEntry(key, value);
        });

        final template = TemplateModel.fromJson(systemTemplate);
        
        // Replace template name
        template.name = template.name.replaceAllMapped(
          RegExp(r'\{(\w+)\}(\d*)'),
          (match) {
            final key = match.group(1) ?? '';
            final number = match.group(2);
            return '${AppLocalizations.of(Get.context!)!.translate(key)}$number';
          }
        );
        
        // Replace category
        template.category = template.category.replaceAllMapped(
          RegExp(r'\{(\w+)\}'),
          (match) => AppLocalizations.of(Get.context!)!.translate(match.group(1) ?? '')
        );
        
        // Replace text elements
        for (var element in template.elements) {
          if (element['type'] == 'text' && element['text'] != null) {
            element['text'] = element['text'].toString().replaceAllMapped(
              RegExp(r'\{(\w+)\}'),
              (match) => AppLocalizations.of(Get.context!)!.translate(match.group(1) ?? '')
            );
          }
        }

        templateName.value = template.name;
        templateSize.value = template.size;
        final elements = template.elements.where((e) => e['type'] == 'background').toList();
        boardElements.value = template.toBoardElements(
            scale: Get.width / elements[0]['size']['width'],
            maxHeight: canvasSize.value.height);
        _textCounter.value = template.getAllTextElements().length;
      } else {
        // Load from SharedPreferences for custom templates
        final userTemplatesJson = SpUtil.getString('user_templates') ?? '[]';
        final List<dynamic> userTemplatesData = jsonDecode(userTemplatesJson);
        final userTemplates = userTemplatesData
            .map((data) => TemplateModel.fromJson(data))
            .toList();
        final template = userTemplates.firstWhere((t) => t.id == templateId);
        templateName.value = template.name;
        templateSize.value = template.size;
        final elements = template.elements.where((e) => e['type'] == 'background').toList();
        boardElements.value = template.toBoardElements(
            scale: Get.width / elements[0]['size']['width'],
            maxHeight: canvasSize.value.height);
        _textCounter.value = template.getAllTextElements().length;
      }
    } catch (e) {
      print('加载失败: $e');
      ToastUtils.showError('加载失败: $e');
    }
  }

  // 辅助方法：捕获预览图
  Future<Uint8List> _capturePreview() async {
    RenderRepaintBoundary boundary =
        boardKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
    ui.Image image = await boundary.toImage(pixelRatio: 3.0);
    final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    return byteData!.buffer.asUint8List();
  }

  // 添加更换片的方法
  Future<void> replaceImage(String elementId) async {
    final XFile? image =
        await _imagePicker.pickImage(source: ImageSource.gallery);
    if (image != null) {
      // 裁剪图片
      final croppedFile = await cropImage(File(image.path));
      if (croppedFile != null) {
        try {
          // 读取原始图片
          final ImageBoardElement element = boardElements.firstWhere(
            (e) => e.id == elementId && e is ImageBoardElement,
          ) as ImageBoardElement;

          // 处理图片颜色
          final processedBytes = await EinkImageProcessor.processImage(
              croppedFile.path, element.processMode.value);

          // 更新图片数据，保持其他属性不变
          element.imagePath.value = processedBytes;
          element.initialImagePath.value = croppedFile.path;
          // 强制更新视图
          boardElements.refresh();
        } catch (e) {
          print('处理图片失败: $e');
          ToastUtils.showError('处理图片失败: $e');
        }
      }
    }
  }

  Future<void> setBackgroundImage(
      BackgroundBoardElement backgroundElement) async {
    try {
      final picker = ImagePicker();
      final pickedFile = await picker.pickImage(source: ImageSource.gallery);

      if (pickedFile != null) {
        // 读取原始图片
        final processedBytes = await EinkImageProcessor.processImage(
            pickedFile.path, backgroundElement.processMode.value);

        // 更新背景元素，存储图片路径而不是File对象
        backgroundElement.backgroundImagePath.value = processedBytes;
        backgroundElement.initialBackgroundImagePath.value = pickedFile.path;
        backgroundElement.backgroundColor.value = Colors.transparent;
      }
    } catch (e) {
      print('处理图片失败: $e');
    }
  }

  // 切换到背景编辑模式
  void showBackgroundEditor() {
    // 查找背景元素
    final backgroundElement = boardElements
        .firstWhereOrNull((element) => element is BackgroundBoardElement);

    if (backgroundElement != null) {
      // 如果找到景元素，选中它
      selectElement(backgroundElement);
    } else {
      // 如果没有找到背景元素，创建一个新的并选中
      final newBackgroundElement = BackgroundBoardElement(
        id: const Uuid().v4(),
        initialPosition: Offset.zero,
        initialSize: canvasSize.value,
        initialColor: Color(0XFFFFFFFF),
      );
      boardElements.add(newBackgroundElement);
      selectElement(newBackgroundElement);
    }
    selectedIndex.value = 4;
  }

  // 清除编辑模式
  void clearEditMode() {
    editMode.value = EditMode.none;
    selectedElement.value = null;
  }

  void applyTemplate(TemplateModel template) {
    try {
      aspectRatio.value = template.width / template.height;

      canvasSize.value =
          Size(Get.size.width, Get.size.width / aspectRatio.value);
      print('aspectRatio: $aspectRatio');
      aspectRatio.refresh();
      // 2. 清除当前所有元素
      boardElements.clear();
      selectedElement.value = null;

      // 3. 从模板数据创建新的元素列表
      final List<dynamic> elementsList = template.elements;

      // 4. 新画板元素
      final elements =
          template.elements.where((e) => e['type'] == 'background').toList();
      boardElements.value = template.toBoardElements(
          scale: Get.width / elements[0]['size']['width'],
          maxHeight: canvasSize.value.height);

      // 5. 更新成员信息
      if (template.memberInfos.isNotEmpty) {
        _textCounter.value = template.memberInfos.length;
      } else {
        _textCounter.value = template.getAllTextElements().length;
      }

      // 6. 显示成功提示
      ToastUtils.showSuccess(AppLocalizations.of(Get.context!)!.translate('template_applied_successfully'));
    } catch (e) {
      print('应用模板失败: $e');
      ToastUtils.showError(AppLocalizations.of(Get.context!)!.translate('apply_template_failed'));
    }
  }

  void initializeData() {
    // 触发一次更新以确保视图刷新
    boardElements.refresh();
    templateName.refresh();
    canvasSize.refresh();
    // 刷新其他可能需要的响应式变量
  }

  toggleScalable(String id) {
    final element = boardElements.firstWhere((e) => e.id == id);
    if (element is TextBoardElement) {
      element.isScalable.value = !element.isScalable.value;
    }
    boardElements.refresh();
  }

  toggleLocked(String id) {
    final element = boardElements.firstWhere((e) => e.id == id);
    if (element is TextBoardElement) {
      element.isLocked.value = !element.isLocked.value;
    }
    print("boardElements: $boardElements");
    boardElements.refresh();
  }
}

// 添加编辑模式枚举
enum EditMode { none, background, element }
